from PySide6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton,
                              QLabel, QTabWidget, QWidget, QColorDialog,
                              QLineEdit, QSpinBox, QFormLayout, QGroupBox,
                              QComboBox, QCheckBox)
from PySide6.QtGui import QColor
from PySide6.QtCore import Qt, QTimer
from PIL import ImageGrab
import pyautogui
from components.color_trigger import ColorSample

# 全局热键支持
try:
    from pynput import keyboard
    import threading
    import time
    GLOBAL_HOTKEY_AVAILABLE = True
except ImportError:
    GLOBAL_HOTKEY_AVAILABLE = False
    print("警告: 未安装 pynput 库，全局热键功能不可用。请运行: pip install pynput")

# Windows 系统特定的高优先级热键支持
try:
    import ctypes
    import ctypes.wintypes
    WINDOWS_HOTKEY_AVAILABLE = True
except ImportError:
    WINDOWS_HOTKEY_AVAILABLE = False

class ColorPickerDialog(QDialog):
    """颜色选择对话框"""
    def __init__(self, parent=None, initial_color=None):
        super().__init__(parent)
        self.setWindowTitle("颜色选择器")
        self.resize(500, 400)

        # 初始颜色
        self.color = initial_color or QColor(255, 255, 255)
        self.algorithm = "RGB"  # 默认算法
        self.tolerance = 10  # 默认容差
        self.hsv_tolerances = {"h": 15, "s": 30, "v": 40}

        # 全局热键相关
        self.global_hotkey_listener = None
        self.windows_hotkey_id = None
        self.hotkey_enabled = False
        self.hotkey_combinations = [
            # 按优先级排序的热键组合
            ('<ctrl>+s', 'Ctrl+S'),
            ('<ctrl>+<shift>+s', 'Ctrl+Shift+S'),
            ('<ctrl>+<alt>+s', 'Ctrl+Alt+S'),
            ('<ctrl>+q', 'Ctrl+Q'),
            ('<alt>+s', 'Alt+S'),
            ('<ctrl>+`', 'Ctrl+`'),
        ]
        self.current_hotkey = None

        # 添加调试信息
        if initial_color:
            print(f"ColorPickerDialog.__init__: 接收到初始颜色 {initial_color.name()} RGB({initial_color.red()}, {initial_color.green()}, {initial_color.blue()})")
        else:
            print(f"ColorPickerDialog.__init__: 使用默认颜色 {self.color.name()}")

        self.setup_ui()
        self.setup_global_hotkey()

    def setup_ui(self):
        main_layout = QVBoxLayout(self)

        # 创建选项卡
        tab_widget = QTabWidget()
        main_layout.addWidget(tab_widget)

        # 吸管取色页
        eyedropper_tab = QWidget()
        tab_widget.addTab(eyedropper_tab, "吸管取色")
        self.setup_eyedropper_tab(eyedropper_tab)

        # 色板选择页
        palette_tab = QWidget()
        tab_widget.addTab(palette_tab, "色板选择")
        self.setup_palette_tab(palette_tab)

        # 代码输入页
        code_tab = QWidget()
        tab_widget.addTab(code_tab, "颜色代码")
        self.setup_code_tab(code_tab)

        # 高级设置区域
        advanced_group = QGroupBox("高级设置")
        advanced_group.setCheckable(True)
        advanced_group.setChecked(False)
        main_layout.addWidget(advanced_group)

        advanced_layout = QFormLayout(advanced_group)

        # 算法选择
        self.algorithm_combo = QComboBox()
        self.algorithm_combo.addItems(["RGB (欧氏距离)", "HSV (色相/饱和度/明度)"])
        self.algorithm_combo.currentIndexChanged.connect(self.on_algorithm_changed)
        advanced_layout.addRow("匹配算法:", self.algorithm_combo)

        # 算法参数面板
        self.params_widget = QWidget()
        advanced_layout.addRow(self.params_widget)

        # 初始化参数面板
        self.setup_rgb_params()



        # 确认/取消按钮
        button_layout = QHBoxLayout()
        self.ok_button = QPushButton("确定")
        self.cancel_button = QPushButton("取消")
        self.ok_button.clicked.connect(self.accept)
        self.cancel_button.clicked.connect(self.reject)
        button_layout.addWidget(self.ok_button)
        button_layout.addWidget(self.cancel_button)
        main_layout.addLayout(button_layout)

        # 初始化所有颜色预览
        self.update_color_preview()

    def setup_eyedropper_tab(self, tab):
        layout = QVBoxLayout(tab)

        # 颜色预览
        preview_layout = QHBoxLayout()
        self.color_sample = ColorSample(self.color, 60)
        preview_layout.addWidget(self.color_sample)

        color_info = QVBoxLayout()
        self.rgb_label = QLabel(f"RGB: {self.color.red()}, {self.color.green()}, {self.color.blue()}")
        self.hex_label = QLabel(f"HEX: {self.color.name()}")
        color_info.addWidget(self.rgb_label)
        color_info.addWidget(self.hex_label)
        preview_layout.addLayout(color_info)
        preview_layout.addStretch()

        layout.addLayout(preview_layout)

        # 说明和按钮
        layout.addWidget(QLabel("点击下方按钮，然后移动鼠标到屏幕上的任意位置选择颜色"))

        self.pick_button = QPushButton("开始取色")
        self.pick_button.clicked.connect(self.start_eyedropper)
        layout.addWidget(self.pick_button)

        # 快捷键提示
        self.hotkey_label = QLabel()
        self.update_hotkey_label()
        layout.addWidget(self.hotkey_label)
        self.setFocusPolicy(Qt.StrongFocus)

        layout.addStretch()

    def setup_palette_tab(self, tab):
        layout = QVBoxLayout(tab)

        # 颜色对话框按钮
        palette_button = QPushButton("打开色板")
        palette_button.clicked.connect(self.open_color_dialog)
        layout.addWidget(palette_button)

        # 颜色预览
        preview_layout = QHBoxLayout()
        self.palette_sample = ColorSample(self.color, 60)
        preview_layout.addWidget(self.palette_sample)

        color_info = QVBoxLayout()
        self.palette_rgb_label = QLabel(f"RGB: {self.color.red()}, {self.color.green()}, {self.color.blue()}")
        self.palette_hex_label = QLabel(f"HEX: {self.color.name()}")
        color_info.addWidget(self.palette_rgb_label)
        color_info.addWidget(self.palette_hex_label)
        preview_layout.addLayout(color_info)
        preview_layout.addStretch()

        layout.addLayout(preview_layout)
        layout.addStretch()

    def setup_code_tab(self, tab):
        layout = QFormLayout(tab)

        # RGB输入
        rgb_layout = QHBoxLayout()
        self.r_input = QSpinBox()
        self.g_input = QSpinBox()
        self.b_input = QSpinBox()
        for spinbox in [self.r_input, self.g_input, self.b_input]:
            spinbox.setRange(0, 255)
            spinbox.setValue(0)  # 明确设置默认值为0
            # 先不连接信号，等初始化完成后再连接
            rgb_layout.addWidget(spinbox)

        print(f"setup_code_tab: 创建RGB输入框，默认值 R={self.r_input.value()}, G={self.g_input.value()}, B={self.b_input.value()}")

        layout.addRow("RGB:", rgb_layout)

        # HEX输入
        self.hex_input = QLineEdit()
        self.hex_input.setPlaceholderText("#RRGGBB")
        # 先不连接信号
        layout.addRow("HEX:", self.hex_input)

        # 颜色预览
        self.code_sample = ColorSample(self.color, 60)
        layout.addRow("预览:", self.code_sample)

        # 初始化输入值
        print(f"setup_code_tab: 设置RGB输入值为 R={self.color.red()}, G={self.color.green()}, B={self.color.blue()}")
        self.r_input.setValue(self.color.red())
        self.g_input.setValue(self.color.green())
        self.b_input.setValue(self.color.blue())
        self.hex_input.setText(self.color.name())

        # 初始化完成后连接信号
        print("setup_code_tab: 连接RGB输入信号")
        for spinbox in [self.r_input, self.g_input, self.b_input]:
            spinbox.valueChanged.connect(self.update_from_rgb_input)
        self.hex_input.textChanged.connect(self.update_from_hex_input)

    def setup_rgb_params(self):
        # 清除现有布局
        if self.params_widget.layout():
            QWidget().setLayout(self.params_widget.layout())

        layout = QFormLayout(self.params_widget)

        # RGB参数 - 欧氏距离容差
        self.tolerance_spin = QSpinBox()
        self.tolerance_spin.setRange(1, 100)
        self.tolerance_spin.setValue(self.tolerance)
        layout.addRow("容差值:", self.tolerance_spin)

    def setup_hsv_params(self):
        # 清除现有布局
        if self.params_widget.layout():
            QWidget().setLayout(self.params_widget.layout())

        layout = QFormLayout(self.params_widget)

        # HSV参数
        self.h_tolerance = QSpinBox()
        self.h_tolerance.setRange(1, 180)
        self.h_tolerance.setValue(self.hsv_tolerances["h"])
        layout.addRow("色相容差(°):", self.h_tolerance)

        self.s_tolerance = QSpinBox()
        self.s_tolerance.setRange(1, 100)
        self.s_tolerance.setValue(self.hsv_tolerances["s"])
        layout.addRow("饱和度容差(%):", self.s_tolerance)

        self.v_tolerance = QSpinBox()
        self.v_tolerance.setRange(1, 100)
        self.v_tolerance.setValue(self.hsv_tolerances["v"])
        layout.addRow("明度容差(%):", self.v_tolerance)

    def on_algorithm_changed(self, index):
        self.algorithm = "RGB" if index == 0 else "HSV"
        if self.algorithm == "RGB":
            self.setup_rgb_params()
        else:
            self.setup_hsv_params()



    def start_eyedropper(self):
        self.hide()  # 隐藏对话框
        QTimer.singleShot(500, self.pick_color)  # 延迟执行，给用户时间移动鼠标

    def pick_color(self, from_global_hotkey=False):
        print(f"🎯 pick_color 方法被调用，from_global_hotkey={from_global_hotkey}")

        # 如果是全局热键触发，不需要隐藏/显示对话框
        was_visible = self.isVisible()

        try:
            x, y = pyautogui.position()
            print(f"🎯 鼠标位置: ({x}, {y})")
            screenshot = ImageGrab.grab()
            pixel = screenshot.getpixel((x, y))
            print(f"🎯 取到的颜色: RGB{pixel}")

            self.color = QColor(*pixel)
            self.update_color_preview()
            print(f"🎯 取色成功: {self.color.name()}")

        except Exception as e:
            print(f"❌ 取色错误: {e}")

        # 只有在对话框原本可见时才重新显示
        if was_visible and not from_global_hotkey:
            self.show()  # 重新显示对话框

    def open_color_dialog(self):
        color = QColorDialog.getColor(self.color, self)
        if color.isValid():
            self.color = color
            self.update_palette_preview()

    def update_color_preview(self):
        # 添加调试信息
        print(f"ColorPickerDialog.update_color_preview: 更新颜色预览为 {self.color.name()} RGB({self.color.red()}, {self.color.green()}, {self.color.blue()})")

        # 更新吸管页面预览
        self.color_sample.setColor(self.color)
        self.rgb_label.setText(f"RGB: {self.color.red()}, {self.color.green()}, {self.color.blue()}")
        self.hex_label.setText(f"HEX: {self.color.name()}")

        # 同步更新其他页面
        self.update_palette_preview()
        self.update_code_preview(update_inputs=True)

    def update_palette_preview(self):
        self.palette_sample.setColor(self.color)
        self.palette_rgb_label.setText(f"RGB: {self.color.red()}, {self.color.green()}, {self.color.blue()}")
        self.palette_hex_label.setText(f"HEX: {self.color.name()}")

        # 同步更新代码页面
        self.update_code_preview(update_inputs=True)

    def update_code_preview(self, update_inputs=False):
        self.code_sample.setColor(self.color)

        if update_inputs:
            # 更新RGB输入框
            self.r_input.blockSignals(True)
            self.g_input.blockSignals(True)
            self.b_input.blockSignals(True)
            self.r_input.setValue(self.color.red())
            self.g_input.setValue(self.color.green())
            self.b_input.setValue(self.color.blue())
            self.r_input.blockSignals(False)
            self.g_input.blockSignals(False)
            self.b_input.blockSignals(False)

            # 更新HEX输入框
            self.hex_input.blockSignals(True)
            self.hex_input.setText(self.color.name())
            self.hex_input.blockSignals(False)

    def update_from_rgb_input(self):
        r = self.r_input.value()
        g = self.g_input.value()
        b = self.b_input.value()
        print(f"update_from_rgb_input: RGB输入变化 R={r}, G={g}, B={b}")
        self.color = QColor(r, g, b)

        # 更新HEX输入框
        self.hex_input.blockSignals(True)
        self.hex_input.setText(self.color.name())
        self.hex_input.blockSignals(False)

        # 更新预览
        self.update_code_preview()
        self.update_color_preview()

    def update_from_hex_input(self):
        hex_code = self.hex_input.text()
        if QColor.isValidColor(hex_code):
            self.color = QColor(hex_code)

            # 更新RGB输入框
            self.r_input.blockSignals(True)
            self.g_input.blockSignals(True)
            self.b_input.blockSignals(True)
            self.r_input.setValue(self.color.red())
            self.g_input.setValue(self.color.green())
            self.b_input.setValue(self.color.blue())
            self.r_input.blockSignals(False)
            self.g_input.blockSignals(False)
            self.b_input.blockSignals(False)

            # 更新预览
            self.update_code_preview()
            self.update_color_preview()

    # 删除重复的 keyPressEvent 方法

    def get_color_data(self):
        """获取颜色数据"""
        result = {
            "color": (self.color.red(), self.color.green(), self.color.blue()),
            "algorithm": self.algorithm
        }

        if self.algorithm == "RGB":
            result["tolerance"] = self.tolerance_spin.value() if hasattr(self, 'tolerance_spin') else self.tolerance
        else:
            result["tolerances"] = {
                "h": self.h_tolerance.value() if hasattr(self, 'h_tolerance') else self.hsv_tolerances["h"],
                "s": self.s_tolerance.value() if hasattr(self, 's_tolerance') else self.hsv_tolerances["s"],
                "v": self.v_tolerance.value() if hasattr(self, 'v_tolerance') else self.hsv_tolerances["v"]
            }



        # 添加调试信息
        print(f"返回颜色数据: {result}")
        return result

    def setup_global_hotkey(self):
        """设置全局热键 - 尝试多种组合直到成功"""
        if not GLOBAL_HOTKEY_AVAILABLE:
            return

        # 首先尝试 Windows 系统级热键（最高优先级）
        if WINDOWS_HOTKEY_AVAILABLE and self.try_windows_hotkey():
            return

        # 然后尝试 pynput 热键
        for hotkey_combo, display_name in self.hotkey_combinations:
            if self.try_pynput_hotkey(hotkey_combo, display_name):
                break

    def try_windows_hotkey(self):
        """尝试使用 Windows 系统级热键（最高优先级）"""
        try:
            import sys
            if sys.platform != 'win32':
                return False

            print("❌ Windows 系统级热键暂时禁用，使用 pynput 热键")
            return False

            # 注意：Windows 系统级热键在某些情况下可能不稳定
            # 暂时禁用，优先使用 pynput 实现

        except Exception as e:
            print(f"Windows 系统级热键设置失败: {e}")
            return False

    def try_pynput_hotkey(self, hotkey_combo, display_name):
        """尝试使用 pynput 热键"""
        try:
            # 停止之前的监听器
            if hasattr(self, 'global_hotkey_listener') and self.global_hotkey_listener:
                try:
                    self.global_hotkey_listener.stop()
                    time.sleep(0.1)  # 等待停止完成
                except:
                    pass

            print(f"🔧 尝试注册热键: {display_name}")

            # 创建全局热键监听器
            hotkey_dict = {hotkey_combo: self.on_global_hotkey_pressed}
            listener = keyboard.GlobalHotKeys(hotkey_dict)

            # 尝试启动监听器
            listener.start()
            time.sleep(0.2)  # 增加等待时间

            # 检查是否成功启动
            if listener.running:
                self.global_hotkey_listener = listener
                self.current_hotkey = ('pynput', display_name)
                print(f"✅ 全局热键设置成功: {display_name}")

                # 测试热键是否真的可用
                print(f"🧪 热键 {display_name} 已注册，请测试是否正常工作")
                return True
            else:
                try:
                    listener.stop()
                except:
                    pass
                print(f"❌ 热键 {display_name} 启动失败，尝试下一个")
                return False

        except Exception as e:
            print(f"❌ 热键 {display_name} 设置失败: {e}")
            return False

    def start_windows_hotkey_listener(self):
        """启动 Windows 热键消息循环"""
        def hotkey_thread():
            try:
                import ctypes
                from ctypes import wintypes

                user32 = ctypes.windll.user32

                # 消息结构
                class MSG(ctypes.Structure):
                    _fields_ = [
                        ("hwnd", wintypes.HWND),
                        ("message", wintypes.UINT),
                        ("wParam", wintypes.WPARAM),
                        ("lParam", wintypes.LPARAM),
                        ("time", wintypes.DWORD),
                        ("pt", wintypes.POINT)
                    ]

                msg = MSG()
                WM_HOTKEY = 0x0312

                print("Windows 热键监听器已启动")

                while self.hotkey_enabled and self.windows_hotkey_id:
                    # 使用 PeekMessage 而不是 GetMessage，避免阻塞
                    if user32.PeekMessageW(ctypes.byref(msg), None, WM_HOTKEY, WM_HOTKEY, 1):  # PM_REMOVE = 1
                        if msg.message == WM_HOTKEY and msg.wParam == self.windows_hotkey_id:
                            print(f"🔥 Windows 系统级热键触发: Ctrl+S")
                            # 热键被按下
                            self.on_global_hotkey_pressed()

                    # 短暂休眠避免占用过多CPU
                    time.sleep(0.01)

            except Exception as e:
                print(f"Windows 热键监听器错误: {e}")

        # 在后台线程中运行
        self.hotkey_thread = threading.Thread(target=hotkey_thread, daemon=True)
        self.hotkey_thread.start()

    def on_global_hotkey_pressed(self):
        """全局热键被按下时的处理"""
        print(f"🔥 全局热键回调被调用，hotkey_enabled={self.hotkey_enabled}")
        if self.hotkey_enabled:
            hotkey_name = self.current_hotkey[1] if self.current_hotkey else "未知"
            print(f"🔥 全局热键触发: {hotkey_name}")

            # 直接调用取色方法，标记为全局热键触发
            try:
                print("🔥 开始执行取色...")
                self.pick_color(from_global_hotkey=True)
                print("🔥 取色执行完成")
            except Exception as e:
                print(f"❌ 全局热键取色失败: {e}")
        else:
            print("❌ 全局热键已禁用，忽略触发")

    def showEvent(self, event):
        """对话框显示时启用全局热键"""
        super().showEvent(event)
        self.enable_global_hotkey()

    def hideEvent(self, event):
        """对话框隐藏时禁用全局热键"""
        super().hideEvent(event)
        self.disable_global_hotkey()

    def closeEvent(self, event):
        """对话框关闭时清理全局热键"""
        self.disable_global_hotkey()
        super().closeEvent(event)

    def enable_global_hotkey(self):
        """启用全局热键"""
        if not self.hotkey_enabled:
            self.hotkey_enabled = True

            if self.current_hotkey:
                hotkey_type, hotkey_name = self.current_hotkey

                if hotkey_type == 'pynput' and self.global_hotkey_listener:
                    try:
                        # pynput 热键在创建时就已经启动了
                        print(f"✅ 全局热键已启用: {hotkey_name}")
                    except Exception as e:
                        print(f"启用 pynput 热键失败: {e}")

                elif hotkey_type == 'windows':
                    print(f"✅ Windows 系统级热键已启用: {hotkey_name}")

            self.update_hotkey_label()

    def disable_global_hotkey(self):
        """禁用全局热键"""
        if self.hotkey_enabled:
            self.hotkey_enabled = False

            if self.current_hotkey:
                hotkey_type, hotkey_name = self.current_hotkey

                if hotkey_type == 'pynput' and self.global_hotkey_listener:
                    try:
                        if self.global_hotkey_listener.running:
                            self.global_hotkey_listener.stop()
                        print(f"❌ 全局热键已禁用: {hotkey_name}")
                    except Exception as e:
                        print(f"禁用 pynput 热键失败: {e}")

                elif hotkey_type == 'windows' and self.windows_hotkey_id:
                    try:
                        import ctypes
                        user32 = ctypes.windll.user32
                        user32.UnregisterHotKey(None, self.windows_hotkey_id)
                        print(f"❌ Windows 系统级热键已禁用: {hotkey_name}")
                    except Exception as e:
                        print(f"禁用 Windows 热键失败: {e}")

            self.update_hotkey_label()

    def update_hotkey_label(self):
        """更新热键提示标签"""
        if not hasattr(self, 'hotkey_label'):
            return

        base_text = "提示: 对话框打开时，可以快速锁定当前鼠标位置的颜色"

        if not GLOBAL_HOTKEY_AVAILABLE:
            text = base_text + "\n❌ 全局热键功能不可用 (需要安装 pynput)"
        elif not self.current_hotkey:
            text = base_text + "\n❌ 全局热键设置失败，所有热键组合都被占用"
        else:
            hotkey_type, hotkey_name = self.current_hotkey
            status = "🟢 已启用" if self.hotkey_enabled else "🔴 已禁用"
            priority = "🔥 最高优先级" if hotkey_type == 'windows' else "⚡ 标准优先级"
            text = f"{base_text}\n{status} 全局热键: {hotkey_name} ({priority})"

        self.hotkey_label.setText(text)

    def keyPressEvent(self, event):
        """处理键盘事件 - 窗口内快捷键"""
        if event.key() == Qt.Key_S and event.modifiers() == Qt.ControlModifier:
            print("🎯 窗口内快捷键触发: Ctrl+S")
            self.pick_color()
        else:
            super().keyPressEvent(event)
